import { world } from "@minecraft/server"

import {
    get_chunk_diagon_position,
    fill_chunk_blcoks,
    is_in_rect_area,
    convertToPlotCoordinates
} from '../utils/Land'

import { LandList } from './data/land/LandList'

const landlist = new LandList()

/**
* 执行地皮保护系统核心逻辑
*/
function enforcePlotProtection() {
    // 1. 获取并预处理地块数据
    const plotMap = preprocessPlotData();
    if (!plotMap) return;

    // 2. 处理所有玩家
    world.getAllPlayers().forEach(player => {
        handlePlayerProtection(player, plotMap);
    });
}

/**
 * 预处理地块数据
 * @returns {Map} 格式化后的地块数据Map
 */
function preprocessPlotData() {
    const rawPlotData = landlist.get_all_plot_data();
    if (!rawPlotData) return null;

    const plotMap = new Map();
    JSON.parse(rawPlotData).forEach(plot => {
        const key = generatePlotKey(plot);
        plotMap.set(key, plot);
    });
    return plotMap;
}

/**
 * 生成地块的唯一键
 * @param {Object} plot 地块对象
 * @returns {string} 唯一标识键
 */
function generatePlotKey(plot) {
    const min = plot.area.min;
    const max = plot.area.max;
    return `${min.x},${min.z}|${max.x},${max.z}`;
}

/**
 * 处理单个玩家的保护逻辑
 * @param {Player} player 玩家对象
 * @param {Map} plotMap 地块数据Map
 */
function handlePlayerProtection(player, plotMap) {
    const { x, y, z } = player.location;

    // 1. 检查是否在地块区域内
    if (!is_in_rect_area(x, z)) return;

    // 2. 区块标记处理
    handleChunkMarking(x, z);

    // 3. 获取玩家所在地块信息
    const plotCoord = convertToPlotCoordinates(x, z);
    const plotKey = generatePlotKey(plotCoord);
    const plot = plotMap.get(plotKey);

    if (!plot) return;

    // 4. 更新玩家状态栏
    updatePlayerActionBar(player, plot.admin);

    // 5. 检查玩家权限
    if (isPlotOwnerOrOp(player, plot.admin)) return;

    // 6. 传送玩家到边界
    teleportPlayerToBoundary(player, plot, x, z, y);
}

/**
 * 处理区块标记
 * @param {number} x 玩家X坐标
 * @param {number} z 玩家Z坐标
 */
function handleChunkMarking(x, z) {
    const chunkPos = get_chunk_diagon_position(x, z);
    fill_chunk_blcoks(chunkPos.x, chunkPos.z);
}

/**
 * 更新玩家动作栏消息
 * @param {Player} player 玩家对象
 * @param {string} ownerName 地块所有者名称
 */
function updatePlayerActionBar(player, ownerName) {
    player.onScreenDisplay.setActionBar(`在${ownerName}的地皮中`);
}

/**
 * 检查玩家是否为地块所有者或OP
 * @param {Player} player 玩家对象
 * @param {string} ownerName 地块所有者名称
 * @returns {boolean} 是否有权限
 */
function isPlotOwnerOrOp(player, ownerName) {
    return ownerName === player.name || player.hasTag("op");
}

/**
 * 传送玩家到最近边界
 * @param {Player} player 玩家对象
 * @param {Object} plot 地块数据
 * @param {number} playerX 玩家X坐标
 * @param {number} playerZ 玩家Z坐标
 * @param {number} playerY 玩家Y坐标
 */
function teleportPlayerToBoundary(player, plot, playerX, playerZ, playerY) {
    // 计算到各边界的距离
    const boundaries = [
        { x: plot.area.min.x, z: playerZ, dist: Math.abs(playerX - plot.area.min.x), isVertical: false, isMin: true },
        { x: plot.area.max.x, z: playerZ, dist: Math.abs(playerX - plot.area.max.x), isVertical: false, isMin: false },
        { x: playerX, z: plot.area.min.z, dist: Math.abs(playerZ - plot.area.min.z), isVertical: true, isMin: true },
        { x: playerX, z: plot.area.max.z, dist: Math.abs(playerZ - plot.area.max.z), isVertical: true, isMin: false }
    ];

    // 找到最近边界点
    const closest = boundaries.reduce((prev, curr) =>
        prev.dist < curr.dist ? prev : curr
    );

    // 计算传送位置（边界外0.5格）
    const buffer = 0.5;
    const newPos = {
        x: closest.isVertical ? playerX :
            closest.x + (closest.isMin ? -buffer : buffer),
        z: !closest.isVertical ? playerZ :
            closest.z + (closest.isMin ? -buffer : buffer),
        y: playerY
    };

    // 执行传送
    player.teleport(newPos);
}

export {
    enforcePlotProtection,
    preprocessPlotData,
    generatePlotKey,
    handlePlayerProtection,
    handleChunkMarking,
    isPlotOwnerOrOp,
    teleportPlayerToBoundary
}